"""
数据库持久化存储实现
用于将聊天历史存储到数据库中
"""

import uuid
from typing import List, Optional
from sqlalchemy.orm import Session
from langchain_core.messages import BaseMessage, HumanMessage, AIMessage, SystemMessage
from langchain_core.chat_history import BaseChatMessageHistory

from app.core.database import SessionLocal
from app.models.conversation import Conversation, Message
from app.models.user import User


class DatabaseChatMessageHistory(BaseChatMessageHistory):
    """基于数据库的聊天历史存储实现"""
    
    def __init__(self, conversation_id: str, user_id: int):
        self.conversation_id = conversation_id
        self.user_id = user_id
        self._messages: List[BaseMessage] = []
        self._loaded = False
    
    def _ensure_loaded(self):
        """确保消息已从数据库加载"""
        if not self._loaded:
            self._load_messages()
            self._loaded = True
    
    def _load_messages(self):
        """从数据库加载消息历史"""
        db: Session = SessionLocal()
        try:
            # 确保会话存在
            conversation = db.query(Conversation).filter(
                Conversation.id == self.conversation_id,
                Conversation.user_id == self.user_id,
                Conversation.is_deleted == False
            ).first()
            
            if not conversation:
                # 如果会话不存在，创建新会话
                conversation = Conversation(
                    id=self.conversation_id,
                    user_id=self.user_id,
                    title="新的聊天"
                )
                db.add(conversation)
                db.commit()
                print(f"--- Created new conversation: {self.conversation_id} for user {self.user_id} ---")
            
            # 加载消息
            messages = db.query(Message).filter(
                Message.conversation_id == self.conversation_id
            ).order_by(Message.message_order).all()
            
            self._messages = []
            for msg in messages:
                if msg.sender == "user":
                    self._messages.append(HumanMessage(content=msg.content))
                elif msg.sender == "bot":
                    self._messages.append(AIMessage(content=msg.content))
                elif msg.sender == "system":
                    self._messages.append(SystemMessage(content=msg.content))
            
            print(f"--- Loaded {len(self._messages)} messages for conversation {self.conversation_id} ---")
            
        except Exception as e:
            print(f"Error loading messages: {e}")
            db.rollback()
        finally:
            db.close()
    
    def _save_message(self, message: BaseMessage):
        """保存单条消息到数据库"""
        db: Session = SessionLocal()
        try:
            # 确定发送者类型
            if isinstance(message, HumanMessage):
                sender = "user"
            elif isinstance(message, AIMessage):
                sender = "bot"
            elif isinstance(message, SystemMessage):
                sender = "system"
            else:
                sender = "system"  # 默认类型
            
            # 获取下一个消息顺序号
            last_message = db.query(Message).filter(
                Message.conversation_id == self.conversation_id
            ).order_by(Message.message_order.desc()).first()
            
            next_order = (last_message.message_order + 1) if last_message else 1
            
            # 创建新消息
            new_message = Message(
                conversation_id=self.conversation_id,
                sender=sender,
                content=message.content,
                message_order=next_order
            )
            
            db.add(new_message)
            
            # 更新会话的更新时间
            conversation = db.query(Conversation).filter(
                Conversation.id == self.conversation_id
            ).first()
            if conversation:
                # 如果是用户的第一条消息且标题还是默认的，更新标题
                if (sender == "user" and 
                    conversation.title == "新的聊天" and 
                    len(message.content) > 0):
                    conversation.title = message.content[:30] + ("..." if len(message.content) > 30 else "")
            
            db.commit()
            print(f"--- Saved message: {sender} -> {message.content[:50]}... ---")
            
        except Exception as e:
            print(f"Error saving message: {e}")
            db.rollback()
        finally:
            db.close()
    
    @property
    def messages(self) -> List[BaseMessage]:
        """获取所有消息"""
        self._ensure_loaded()
        return self._messages
    
    def add_message(self, message: BaseMessage) -> None:
        """添加消息"""
        self._ensure_loaded()
        self._messages.append(message)
        self._save_message(message)
    
    def add_user_message(self, message: str) -> None:
        """添加用户消息"""
        self.add_message(HumanMessage(content=message))
    
    def add_ai_message(self, message: str) -> None:
        """添加AI消息"""
        self.add_message(AIMessage(content=message))
    
    def add_system_message(self, message: str) -> None:
        """添加系统消息"""
        self.add_message(SystemMessage(content=message))
    
    def clear(self) -> None:
        """清空消息历史"""
        self._messages = []
        
        # 从数据库中删除消息（软删除会话）
        db: Session = SessionLocal()
        try:
            conversation = db.query(Conversation).filter(
                Conversation.id == self.conversation_id,
                Conversation.user_id == self.user_id
            ).first()
            
            if conversation:
                # 删除所有消息
                db.query(Message).filter(
                    Message.conversation_id == self.conversation_id
                ).delete()
                
                # 重置会话标题
                conversation.title = "新的聊天"
                
                db.commit()
                print(f"--- Cleared conversation {self.conversation_id} ---")
        
        except Exception as e:
            print(f"Error clearing messages: {e}")
            db.rollback()
        finally:
            db.close()


def get_user_conversations(user_id: int, limit: int = 50) -> List[dict]:
    """获取用户的会话列表"""
    db: Session = SessionLocal()
    try:
        conversations = db.query(Conversation).filter(
            Conversation.user_id == user_id,
            Conversation.is_deleted == False
        ).order_by(Conversation.updated_at.desc()).limit(limit).all()
        
        return [conv.to_dict() for conv in conversations]
    
    except Exception as e:
        print(f"Error getting user conversations: {e}")
        return []
    finally:
        db.close()


def delete_conversation(conversation_id: str, user_id: int) -> bool:
    """删除用户的会话（软删除）"""
    db: Session = SessionLocal()
    try:
        conversation = db.query(Conversation).filter(
            Conversation.id == conversation_id,
            Conversation.user_id == user_id
        ).first()
        
        if conversation:
            conversation.is_deleted = True
            db.commit()
            print(f"--- Deleted conversation {conversation_id} for user {user_id} ---")
            return True
        
        return False
    
    except Exception as e:
        print(f"Error deleting conversation: {e}")
        db.rollback()
        return False
    finally:
        db.close()


def create_conversation(user_id: int, title: str = "新的聊天") -> str:
    """为用户创建新会话"""
    conversation_id = str(uuid.uuid4())
    
    db: Session = SessionLocal()
    try:
        conversation = Conversation(
            id=conversation_id,
            user_id=user_id,
            title=title
        )
        db.add(conversation)
        db.commit()
        
        print(f"--- Created conversation {conversation_id} for user {user_id} ---")
        return conversation_id
    
    except Exception as e:
        print(f"Error creating conversation: {e}")
        db.rollback()
        return None
    finally:
        db.close()
